package com.hawk.eye.client.notify.listener;

import ch.qos.logback.classic.LoggerContext;
import com.hawk.eye.client.async.NamedThreadFactory;
import com.hawk.eye.client.config.HawkEyeProperties;
import com.hawk.eye.client.toolkit.HawkEyeLogger;
import com.hawk.eye.client.async.task.RequestServerTask;
import com.hawk.eye.client.constant.HawkEyeConstant;
import com.hawk.eye.client.notify.event.AbstractConnectEvent;
import com.hawk.eye.client.notify.event.RequestDoneEvent;
import com.hawk.eye.client.notify.event.RequestFailEvent;
import com.hawk.eye.client.toolkit.ServiceAuthHolder;
import com.hawk.eye.client.util.ThreadUtil;
import com.hawk.eye.common.core.ApiResult;
import com.hawk.eye.common.encipher.MessageEncipher;
import com.hawk.eye.common.client.IClient;
import com.hawk.eye.common.model.ServiceAuthData;
import com.hawk.eye.common.utils.Kv;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

/**
 * @className: HawkEyeConnectListener
 * @description: 连接事件的监听器
 * @author: salad
 * @date: 2023/9/16
 **/
@Slf4j
@RequiredArgsConstructor
public class HawkEyeConnectListener implements ApplicationListener<AbstractConnectEvent> {

    private final IClient client;

    private final HawkEyeProperties properties;

    private final MessageEncipher messageEncipher;

    @Override
    public void onApplicationEvent(@NotNull AbstractConnectEvent event) {
        Kv kv = Kv.create();
        //连接失败
        if (event instanceof RequestFailEvent) {
            RequestFailEvent connectEvent = (RequestFailEvent) event;
            kv = (Kv) connectEvent.getSource();
            HawkEyeLogger.errorWithSkipSend(this.getClass(), "HawkEyeServer授权失败,请检查相关配置");
        }
        //连接成功
        if (event instanceof RequestDoneEvent) {
            RequestDoneEvent connectEvent = (RequestDoneEvent) event;
            kv = (Kv) connectEvent.getSource();
            ApiResult<?> apiResult = (ApiResult<?>) kv.get(HawkEyeConstant.RESULT);
            if (apiResult == null) {
                HawkEyeLogger.errorWithSkipSend(this.getClass(), "HawkEyeServer授权失败,请检查相关配置");
                return;
            }
            ServiceAuthData sad = (ServiceAuthData) apiResult.getData();
            //如果为空则说明HawkEyeServer没有配置该服务的告警配置
            if (sad == null) {
                log.warn("HawkEyeServer未添加该服务的告警配置信息");
                return;
            }
            //将授权信息保存到环境变量中
            ServiceAuthHolder.setAuthData(sad);
            ServiceAuthHolder.setServerAddr(properties.getHawkEyeServerAddress());
            log.info("HawkEyeServer授权成功");
        }
        //如果是第一次建立连接，会开启一个定时任务，每隔一段时间就重新连接刷新token
        if (Boolean.TRUE.equals(kv.get(HawkEyeConstant.FIRST_CONNECT))) {
            ScheduledExecutorService scheduledExecutorService =
                    Executors.newScheduledThreadPool(1, new NamedThreadFactory(HawkEyeConstant.REPULL_THREAD_PREFIX));
            scheduledExecutorService.scheduleWithFixedDelay(
                    new RequestServerTask(client, properties.getHawkEyeServerAddress(), messageEncipher, Boolean.FALSE),
                    properties.getConnectTaskDelayTime(), properties.getConnectTaskDelayTime(), properties.getDelayTimeUnit());
            //添加一个关闭钩子，清理定时任务和授权信息
            Runtime.getRuntime().addShutdownHook(new Thread(() -> {
                ThreadUtil.shutdownAndAwaitTermination(scheduledExecutorService);
            }));
        }
    }

}